package com.flame.workflow.re.controller;

import com.flame.core.protocol.PageResult;
import com.flame.core.protocol.Result;
import com.flame.workflow.constants.ModelConstants;
import com.flame.workflow.exception.WorkflowExcetionMessage;
import com.flame.workflow.exception.WorkflowRuntimeException;
import com.flame.workflow.re.controller.vo.DeploymentVo;
import com.flame.workflow.re.controller.vo.ModelDetailVo;
import com.flame.workflow.re.controller.vo.ModelVo;
import com.flame.workflow.re.entity.*;
import com.flame.workflow.re.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * flame_workflow_re_model 流程模型定义表
 *
 * @author 吴欣童
 * @since 2023-05-04 19:54:59
 */
@RestController
public class ModelController {

    @Autowired
    private ModelService modelService;

    @Autowired
    private FormService formService;

    @Autowired
    private FormComponentService formComponentService;

    @Autowired
    private NodeService nodeService;

    @Autowired
    private PropertyService propertyService;

    @Autowired
    private DeploymentService deploymentService;

    @PostMapping("/workflow/re/model/deploment/list")
    public Result pageDeployment(@RequestBody DeploymentVo deploymentVo) {
        return Result.success(deploymentService.listDeployment(deploymentVo));
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/workflow/re/model/publish")
    public Result publish(@RequestBody ModelDetailVo modelDetailVo) {
        // 保存流程模型信息
        Long modelId = modelDetailVo.getModel().getModelId();
        Integer modelVersion = modelDetailVo.getModel().getModelVersion();
        modelService.maintainModel(modelDetailVo.getModel());
        formService.maintainForm(modelDetailVo.getForm());
        formComponentService.maintainItemList(modelId, modelVersion, modelDetailVo.getFormComponentList());
        nodeService.maintainNodeList(modelId, modelVersion, modelDetailVo.getNodeList());
        propertyService.maintainPropertyList(modelId, modelVersion, modelDetailVo.getPropertyList());

        // 更新部署的模型版本
        if (ModelConstants.MODEL_STATUS_ACTIVE.equals(modelDetailVo.getModel().getModelStatus())) {
            Deployment deployment = new Deployment();
            deployment.setModelId(modelId);
            deployment.setModelVersion(modelVersion);
            deploymentService.maintainDeployment(deployment);
        }

        // 版本号 + 1，创建新的待发布新模型
        Model model = modelDetailVo.getModel();
        model.setModelVersion(modelVersion + 1);
        modelService.maintainModel(model);
        Form form = modelDetailVo.getForm();
        form.setModelVersion(modelVersion + 1);
        formService.maintainForm(form);
        formComponentService.maintainItemList(modelId, modelVersion + 1, modelDetailVo.getFormComponentList());
        nodeService.maintainNodeList(modelId, modelVersion + 1, modelDetailVo.getNodeList());
        propertyService.maintainPropertyList(modelId, modelVersion + 1, modelDetailVo.getPropertyList());
        return Result.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/workflow/re/model/maintain")
    public Result maintain(@RequestBody ModelDetailVo modelDetailVo) {
        Long modelId = modelDetailVo.getModel().getModelId();
        Integer modelVersion = modelDetailVo.getModel().getModelVersion();
        modelService.maintainModel(modelDetailVo.getModel());
        formService.maintainForm(modelDetailVo.getForm());
        formComponentService.maintainItemList(modelId, modelVersion, modelDetailVo.getFormComponentList());
        nodeService.maintainNodeList(modelId, modelVersion, modelDetailVo.getNodeList());
        propertyService.maintainPropertyList(modelId, modelVersion, modelDetailVo.getPropertyList());
        return Result.success();
    }

    @PostMapping("/workflow/re/model")
    public Result getModel(@RequestBody Model model) {
        Model dbModel = modelService.getModel(model.getModelId(), model.getModelVersion());
        Form form = formService.getForm(model.getModelId(), model.getModelVersion());
        List<FormComponent> formComponentList = formComponentService.getFormComponentList(model.getModelId(), model.getModelVersion());
        List<Node> nodeList = nodeService.getNodeList(model.getModelId(), model.getModelVersion());
        List<Property> allProperties = propertyService.getAllProperties(dbModel, formComponentList, nodeList);

        ModelDetailVo modelDetailVo = new ModelDetailVo();
        modelDetailVo.setModel(dbModel);
        modelDetailVo.setForm(form);
        modelDetailVo.setFormComponentList(formComponentList);
        modelDetailVo.setNodeList(nodeList);
        modelDetailVo.setPropertyList(allProperties);
        return Result.success(modelDetailVo);
    }

    @PostMapping("/workflow/re/model/page")
    public PageResult pageModel(@RequestBody ModelVo modelVo) {
        return PageResult.success(modelService.pageModel(modelVo));
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/workflow/re/model/add")
    public Result addModel(@RequestBody @Validated Model model) {
        modelService.addModel(model);
        return Result.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/workflow/re/model/update")
    public Result updateModel(@RequestBody @Validated Model model) {
        modelService.updateModel(model);
        return Result.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/workflow/re/model/stauts/update")
    public Result updateModelStatus(@RequestBody @Validated Model model) {
        if (ModelConstants.MODEL_STATUS_ACTIVE.equals(model.getModelStatus())) {
            if (model.getModelVersion() > 1) {
                Deployment deployment = new Deployment();
                deployment.setModelId(model.getModelId());
                deployment.setModelVersion(model.getModelVersion() - 1);
                deploymentService.maintainDeployment(deployment);
            } else {
                throw new WorkflowRuntimeException(WorkflowExcetionMessage.NO_AVALIABLE_VERSION);
            }
        }
        if (ModelConstants.MODEL_STATUS_UNACTIVE.equals(model.getModelStatus())) {
            Deployment deployment = new Deployment();
            deployment.setModelId(model.getModelId());
            deployment.setModelVersion(model.getModelVersion());
            deploymentService.deleteDeployment(deployment);
        }
        modelService.updateModel(model);
        return Result.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/workflow/re/model/delete")
    public Result deleteModel(@RequestBody @Validated Model model) {
        modelService.deleteModel(model);
        return Result.success();
    }
}
